Esercitazione sulla Regressione Lineare¶

Istruzioni¶

Valgono le stesse istruzioni delle esercitazioni precedenti.

Scrivi il programma Python nella cella sotto il testo dell'esercizio (o creane una nuova). Stampa sempre a video il risultato finale per verificare la correttezza dell'esercizio. Talvolta richiamiamo alcuni concetti importanti in una cella di codice sotto il testo dell'esercizio, prova a eseguirla ed eventualmente modificarla per assicurarti di aver capito il necessario.

Nota. Alcuni esercizi potrebbero richiedere una semplice risposta a delle domande. In questo caso potete scrivere la soluzione in una cella di tipo "Markdown".

Consegna¶

Valgono le regole delle esercitazioni precedenti.

E' obbligatorio consegnare la soluzione di tutti gli esercizi (tranne quelli marcati come opzionali) entro l'inizio della lezione successiva (in questo caso entro Lunedi' prossimo), nell'apposito assignment su iCorsi. Per consegnare:

  • eseguire l'intero notebook partendo da zero (Kernel -> Restart & Run All), e controllare che le soluzioni siano quelle attese;
  • esportare il notebook in formato html (File -> Download as...) e consegnare il file risultante.

Nel caso non abbiate potuto completare uno o piu' esercizi, descrivete il problema incontrato e consegnate comunque il file con il resto delle soluzioni.

Esercizio 1¶

1.1¶

Si consideri lo scatter plot in figura, che riporta la relazione tra la variabile indipendente x e la variabile target y. FigRegr11

Una tra le seguenti 4 rette rappresenta il modello di regressione lineare che minimizza il sum-of-squares error (SSE). Quale? Motivate la vostra risposta.

  • $y = x-4$
  • $y = 2x-4$
  • $y = 2x+4$
  • $y = x-4$

Soluzione esercizio 1.1

  • $y = 2x+4$ è la funzione con sse minore poichè i punti del plot e quelli della retta hanno uno scarto quadratico minore rispetto alle altre funzioni
In [1]:
import numpy as np
x1=np.array(range(-10,11))
y1=2*x1+4
w_hat=np.sum((x1-np.mean(x1))*(y1-np.mean(y1)))/np.sum((x1-np.mean(x1))**2)
b_hat=np.mean(y1)-w_hat*np.mean(x1)
import plotly.express as plx
plx.scatter(x1,y1)
In [2]:
x1=np.array(range(-10,11))
y1=2*x1-4
w_hat=np.sum((x1-np.mean(x1))*(y1-np.mean(y1)))/np.sum((x1-np.mean(x1))**2)
b_hat=np.mean(y1)-w_hat*np.mean(x1)
import plotly.express as plx
plx.scatter(x1,y1)
In [3]:
x1=np.array(range(-10,11))
y1=x1-4
w_hat=np.sum((x1-np.mean(x1))*(y1-np.mean(y1)))/np.sum((x1-np.mean(x1))**2)
b_hat=np.mean(y1)-w_hat*np.mean(x1)
import plotly.express as plx
plx.scatter(x1,y1)

1.2¶

Scrivere una funzione Python computePerformance(x,y,w,b) che calcola il SSE e il coefficiente di determinazione $R^2$ tra le osservazioni e la retta di regressione $y = wx + b$.

La funzione riceve come argomenti di ingresso:

  • x: numpy array contente una sequenza della variabile esplicativa
  • y: numpy array della stessa dimensione di $x$ contente una sequenza della variabile target
  • w: coefficiente angolare della retta di regressione
  • b: valore dell'intercetta della retta di regressione

e restituisce il SSE e l' $R^2$.

Testate la funzione computePerformance(x,y,w,b) per vari valori di $w$ e $b$ su un set di osservazioni generato in questo modo:

  • x: array di dimensione 1000 che assume valori casuali (es. valori generati da una distribuzione Gaussiana con media nulla e varianza unitaria)
  • y=3x-1 + errore, dove errore è un array di variabili casuali Gaussiane a media nulla e varianza $0.1$, e generato col comando errore = 0.1*np.random.randn(1000)

Se non avete fatto errori, dovreste osservare che il SSE è "basso" e l' $R^2$ è "prossimo a 1" per valori di $w$ e $b$ vicini a $3$ e $-1$.

In [4]:
# Solution
import numpy as np
from sklearn.metrics import r2_score
def computePerfomance(x,y,w,b):
    y_hat = b + w * x
    e = y - y_hat
    output= dict({"sse":np.sum(e**2),"r2":    r2_score(x,y)})

    return output
x=np.random.randn(1000)
errore = 0.1*np.random.randn(1000)
y=3*x-1+errore
computePerfomance(x,y,3,-1)
Out[4]:
{'sse': 10.197825082491487, 'r2': -3.7058267843136887}

Regressione lineare tramite pacchetto scikit-learn¶

Il pacchetto Python scikit-learn ci permette di calcolare un modello di regressione lineare (sia semplice che multipla) con pochi comandi e in maniera molto efficiente.

Familiarizzate con i comandi principli si scikit-learn eseguendo le celle di questo esercizio oppure guardano gli esempi disponibili online.

La seguente cella importa il modulo linear_model dal pacchetto scikit-learn dove sono definite classi e metodi necessari per costruire un modello di regressione lineare del tipo y = x*w+b. Una volta importato il modulo linear_model, viene costruito un oggetto linRegr della classe LinearRegression. All'oggetto linRegrviene applicato il metodo fit per ricavare il modello di regressione.

Nota: il metoto fit riceve come parametri di ingresso: - x: array di dimensione DUE con i valori delle variabili esplicative. L'array ha m righe e n colonne (dove m è il numero di osservazioni, e n è il numero di variabili esplicative. Nota bene: (i) n=1 nel caso di regressione semplice, (ii) x deve sempre essere un array di dimensione DUE!! Se avete un array di dimensione 1, fate il reshape dell'array tramite il comando np.reshape per trasformarlo in un vettore colonna di dimensione DUE) - y: array con i valori della variabile target di lunghezza m. Nota: y puo' anche essere un array di dimensione 1.

Una volta eseguito il comando fit, potete visualizzare i parametri w e b del modello di regressione accedendo agli attributi coef_ e intercept_ dell'oggetto linRegr.

In [5]:
from sklearn import linear_model

# Definisco l'oggetto della classe LinearRegression
linRegr = linear_model.LinearRegression()


m = len(x) # Numero di osservazioni
x = np.reshape(x,(m,1)) # Trasformo l'array delle variabili esplicative in un array di dimensione 2 (con m righe e 1 colonna)


# Costruisco il modello di regressione lineare
linRegr.fit(x,y)

# Stampo i parametri w e b del modello di regressione
w = linRegr.coef_
b = linRegr.intercept_
print(f"Parametri w: {w}")
print(f"Intercetta b: {b}")
Parametri w: [2.99774425]
Intercetta b: -1.0033822069493066

Dato un qualunque set di valori della variabile indipendente x, possiamo usare il modello di regressione lineare appena calcolato per stimare il valore della variabile target y. Basta usare il metodo predict e fornire come ingresso i valori della variabile indipendente.

In [6]:
import plotly.offline as py
import plotly.graph_objs as go
py.init_notebook_mode(connected=True)

# Predico l'uscita per i valori della variabile indipendente x
yhat = linRegr.predict(x)

# Plotto variabile target (vera) e variabile target stimata dal modello di regressione lineare
# ATTENZIONE: quando plottate lo scatter plot con plotly, i valori delle coordinate 'x' e 'y' devono essere array di dimensione UNO!!!!!

trace = [go.Scatter(x = x[:,0], y = y, mode = 'markers', name = 'Variabile target misurata'),
         go.Scatter(x = x[:,0], y = yhat, mode = 'markers', name = 'Variabile target stimata')]

layout = go.Layout(xaxis = dict(title = 'x: variabile esplicativa'), 
                   yaxis = dict(title = 'y: variabile target'))

fig = go.Figure(trace, layout)
py.iplot(fig)                    

Il metodo score fornisce il coefficiente di determinazione $R^2$ per il modello di regressione lineare calcolato e per un set di valori della variabile esplicativa x e della corrispondente variabile target y.

In [7]:
R2Tool = linRegr.score(x,y)
R2Tool 
Out[7]:
0.9988548563314587

1.3.1¶

Ripete l'esercizio sulla regressione semplice visto a lezione in cui si analizzava la relazione tra lunghezza della mano e altezza di una persona.

Nello specifico:

  • Calcolate i parametri del modello di regressione lineare y=x*w+b utilizzando il pacchetto scikit-learn
  • Disegnare in un unico grafico lo scatter plot delle osservazioni e la retta di regressione
  • Calcolate il coeffiente di determinazione R^2 utilizzando il metodo score
  • Usate il metodo predict per calcolate il valore della funzione y = x*w+b per ogni valore di x. Calcolate il SSE
In [8]:
# Punto 1

import pandas as pd

import ssl
ssl._create_default_https_context = ssl._create_unverified_context
# Leggiamo il dataset
df = pd.read_table("http://users.stat.ufl.edu/~winner/data/stature_hand_foot.dat",
                   delim_whitespace=True, names = ["id", "sex", "stature", "hand", "foot"])
x = df["hand"].values # Variabile esplicativa
y = df["stature"].values # Variabile target 
m = len(x)
x = np.reshape(x,(m,1))

# Creiamo oggetto della classe LinearRegression
regLin = linear_model.LinearRegression()

# Calcoliamo modello di regressione lineare
regLin.fit(x,y)

w = regLin.coef_
b = regLin.intercept_

print(f"Modello di regression lineare: y=x{w}+{b}")
Modello di regression lineare: y=x[6.14601322]+451.4775962062031
In [9]:
# Punto 2
predictY=regLin.predict(x)
trace=[go.Scatter(x=x[:,0],y=y, mode='markers', name = 'Variabile target misurata'),go.Scatter(x=x[:,0],y=predictY,mode='markers',name = 'Variabile target predetta')]

layout = go.Layout(xaxis = dict(title = 'x: variabile esplicativa'),
                   yaxis = dict(title = 'y: variabile target'))

fig = go.Figure(trace, layout)
fig.show()
In [10]:
# Punto 3
regLin.score(x,y)
Out[10]:
0.7623590030663299
In [11]:
# Punto 4
from sklearn.metrics import mean_squared_error
mean_squared_error(y,predictY)
Out[11]:
2082.3004856701587

Esercizio 2¶

Si consideri il dataset kc_house_data.csv disponibile su iCorsi, che contiene informazioni sugli appartamenti venduti da Maggio 2014 a Maggio 2015 nella King County. Tra le informazioni disponibili sono presenti prezzo di vendita, caratteristiche dell'abitazione (es., dimensione dell'abitazione, numero di camere da letto, rapporto tra numero di bagni e camere da letto, etc.). Informazioni sul dataset si possono trovare QUI.

L'obbiettivo di questo esercizio è costruire un modello di regressione lineare (sia semplice che multipla) che spieghi la relazione tra le variabili indipendenti (caratteristiche dell'abitazione) e la variabile target (prezzo di vendita).

Eseguite la cella per caricare il dataset (caricheremo solo l'1% dell'intero dataset). Tramite il comando train_test_split, dividiamo in maniera randomica il dataset appena caricato in 2 datasets disgiunti, che chiameremo dfTrain e dfTest e che costituiranno, rispettivamente, il set di training (usato per costruire il modello di regressione lineare), e il set di test (usato per valutare le performance del modello di regressione costruito). La dimensione del set di training e del set di test sono il 70% e 30% del dataset.

Visualizzate i dataset caricati, guardate quali sono i nomi degli attributi e capite cosa rappresentano, aiutandovi con la descrizione disponibile online al seguente link.

In [12]:
import pandas as pd
import numpy as np
from sklearn import linear_model
from sklearn.model_selection import train_test_split

df = pd.read_csv('data/kc_house_data.csv')
df = df.sample(frac=0.01, random_state=42) # carico solo l'1% del dataset originale

[dfTrain, dfTest] = train_test_split(df, test_size=0.3, random_state=42) # la dimensione del test set è il 30% del dataset 

# Visualizziamo come è fatto il dataset
print('Training dataset:')
dfTrain
Training dataset:
Out[12]:
id date price bedrooms bathrooms sqft_living sqft_lot floors waterfront view ... grade sqft_above sqft_basement yr_built yr_renovated zipcode lat long sqft_living15 sqft_lot15
12838 3296000040 20140923T000000 542000.0 3 2.50 1990 15985 1.0 0 0 ... 8 1540 450 1964 0 98007 47.6205 -122.141 2470 10125
12618 6617500085 20150422T000000 500000.0 4 2.50 2900 5760 1.0 0 0 ... 8 1660 1240 1959 0 98118 47.5500 -122.272 2250 6098
4296 7116500705 20150129T000000 156000.0 2 1.00 920 5889 1.0 0 0 ... 6 920 0 1950 0 98002 47.3012 -122.218 1210 6180
9414 5700003630 20140630T000000 1925000.0 5 4.25 4830 8050 2.5 0 2 ... 11 3710 1120 1914 0 98144 47.5789 -122.286 4470 9194
6914 6821600005 20150403T000000 710000.0 4 1.75 2120 5400 1.0 0 0 ... 8 1060 1060 1941 0 98199 47.6501 -122.395 2052 6000
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
8288 9828200762 20140628T000000 650000.0 2 1.00 1050 2542 1.0 0 0 ... 7 880 170 1904 0 98122 47.6172 -122.298 1620 1809
16941 2626119028 20150323T000000 160000.0 3 1.00 1140 3240 1.5 0 0 ... 6 1140 0 1910 0 98014 47.7093 -121.364 1140 4700
15473 6072400280 20140619T000000 619850.0 4 2.50 2270 9247 1.0 0 0 ... 8 1500 770 1972 0 98006 47.5602 -122.176 2270 9163
2350 3298201170 20141110T000000 350000.0 3 1.00 940 7811 1.0 0 0 ... 6 940 0 1959 0 98008 47.6195 -122.118 1180 7490
14984 4136960010 20150327T000000 480000.0 5 3.50 3480 12821 2.0 0 2 ... 10 2890 590 2004 0 98092 47.2641 -122.215 3400 9870

151 rows × 21 columns

2.1¶

Utilizzando il dataset di training dfTrain caricato prima, costruite un modello di regressione lineare semplice che spieghi la relazione tra la variabile target price (prezzo di vendita in $) e la variabile esplicativa sqft_living (dimensione dell'abitazione in square feet).

Nello specifico, si eseguano i seguenti punti:

  • Generate lo scatter plot delle osservazioni. Notate una relazione tra la variabile esplicativa e la variabile target?
  • Calcolate i parametri del modello di regressione lineare y=x*w+b(Hint: usare i comandi del pacchetto scikit-learn)
  • Disegnare in un unico grafico lo scatter plot delle osservazioni del trainig set e la retta di regressione.
  • Calcolate il valore della funzione y = x*w+b per ogni valore di x del training set e del test set (Hint: usate il comando predict). Si plottino, in 2 figure separate, i residui sul training test e sul test set.
  • Calcolate il coeffiente di determinazione R^2e il SSE sia sul training set che sul test set.

Nota: Si esegua la cella sotto per estrarre dal dataset di training e test la variabile target price e la variabile esplicativa sqft_living

In [13]:
# Carichiamo le variabili che ci interessano

yTrain = dfTrain['price'].values
xTrain = dfTrain['sqft_living'].values

yTest = dfTest['price'].values
xTest = dfTest['sqft_living'].values

print(f"Length of trainig dataset: {len(yTrain)}")
print(f"Length of test dataset: {len(yTest)}")


# Facciamo il reshape delle variabili esplicative per avere array di dimensione 2 con m righe e 1 colonna
mTrain = len(xTrain)
mTest = len(xTest)

xTrain = np.reshape(xTrain,(mTrain,1))
xTest = np.reshape(xTest,(mTest,1))
Length of trainig dataset: 151
Length of test dataset: 65
In [14]:
# Solution (Punto 1)
trace=[go.Scatter(x=xTrain[:,0],y=yTrain,mode="markers")]
layout = go.Layout(xaxis = dict(title = 'sqft_living'),
                   yaxis = dict(title = 'price'))
fig=go.Figure(trace,layout)
fig.show()
In [15]:
# Solution (Punto 2)
regLin= linear_model.LinearRegression()
regLin.fit(xTrain,yTrain)
print(f"w={regLin.coef_} b={regLin.intercept_}")
w=[236.68349315] b=38436.72043428547
In [16]:
# Solution (Punto 3)


prediction=regLin.predict(xTrain)

trace=[go.Scatter(x=xTrain[:,0],y=yTrain,mode="markers",name="dataset data"),go.Scatter(x=xTrain[:,0],y=prediction,mode="markers", name="prediction")]
layout = go.Layout(xaxis = dict(title = 'sqft_living'),
                   yaxis = dict(title = 'price'))
fig=go.Figure(trace,layout)
fig.show()

trace=[go.Scatter(x=xTrain[:,0],y=yTrain-prediction,mode="markers",name="residual"),go.Scatter(x=xTrain[:,0],y=prediction,mode="markers", name="regretion line")]
layout = go.Layout(xaxis = dict(title = 'sqft_living'),
                   yaxis = dict(title = 'price'))
fig=go.Figure(trace,layout)
fig.show()
In [17]:
# Solution (Punto 4)
regLin= linear_model.LinearRegression()
regLin.fit(xTest,yTest)
prediction=regLin.predict(xTest)
trace=[go.Scatter(x=xTest[:,0],y=yTest,mode="markers",name="dataset data"),go.Scatter(x=xTest[:,0],y=prediction,mode="markers", name="prediction")]
layout = go.Layout(xaxis = dict(title = 'sqft_living'),
                   yaxis = dict(title = 'price'))
fig=go.Figure(trace,layout)
fig.show()


trace=[go.Scatter(x=xTest[:,0],y=yTest-prediction,mode="markers",name="residual"),go.Scatter(x=xTest[:,0],y=prediction,mode="markers", name="regretion line")]
layout = go.Layout(xaxis = dict(title = 'sqft_living'),
                   yaxis = dict(title = 'price'))
fig=go.Figure(trace,layout)
fig.show()
In [18]:
# Solution (Punto 5)
print(f"train r^2= {regLin.score(xTrain,yTrain)}")
print(f"test r^2= {regLin.score(xTest,yTest)}")
train r^2= 0.5196643046455451
test r^2= 0.3700267105716897

2.2¶

Si ripetano i punti dell'esercizio precedente, utilizzando come variabile target sempre il prezzo di vendita, ma come variabile esplicativa non piu' la dimensione dell'abitazione, ma la variabile grade. La variabile grade assume valori tra 1 e 13 e rappresenta la classe di appartenenza dell'abitazione data dalla King County sulla base di una perizia imparziale.

In [19]:
# Solution (punto 0: Carichiamo le variabili che ci interessano)

yTrain = dfTrain['price'].values
xTrain = dfTrain['grade'].values

yTest = dfTest['price'].values
xTest = dfTest['grade'].values

# Facciamo il reshape delle variabili esplicative per avere array di dimensione 2 con m righe e 1 colonna
mTrain = len(xTrain)
mTest = len(xTest)

xTrain = np.reshape(xTrain,(mTrain,1))
xTest = np.reshape(xTest,(mTest,1))
In [20]:
# Solution (Punto 1)
trace=[go.Scatter(x=xTrain[:,0],y=yTrain,mode="markers")]
layout = go.Layout(xaxis = dict(title = 'sqft_living'),
                   yaxis = dict(title = 'price'))
fig=go.Figure(trace,layout)
fig.show()
In [21]:
# Solution (Punto 2)
regLin= linear_model.LinearRegression()
regLin.fit(xTrain,yTrain)
print(f"w={regLin.coef_} b={regLin.intercept_}")
w=[182811.66205833] b=-851070.4108805379
In [22]:
# Solution (Punto 3)


prediction=regLin.predict(xTrain)

trace=[go.Scatter(x=xTrain[:,0],y=yTrain,mode="markers",name="dataset data"),go.Scatter(x=xTrain[:,0],y=prediction,mode="markers", name="prediction")]
layout = go.Layout(xaxis = dict(title = 'grade'),
                   yaxis = dict(title = 'price'))
fig=go.Figure(trace,layout)
fig.show()

trace=[go.Scatter(x=xTrain[:,0],y=yTrain-prediction,mode="markers",name="residual"),go.Scatter(x=xTrain[:,0],y=prediction,mode="markers", name="regretion line")]
layout = go.Layout(xaxis = dict(title = 'grade'),
                   yaxis = dict(title = 'price'))
fig=go.Figure(trace,layout)
fig.show()
In [23]:
# Solution (Punto 4)
regLin= linear_model.LinearRegression()
regLin.fit(xTest,yTest)
prediction=regLin.predict(xTest)
trace=[go.Scatter(x=xTest[:,0],y=yTest,mode="markers",name="dataset data"),go.Scatter(x=xTest[:,0],y=prediction,mode="markers", name="prediction")]
layout = go.Layout(xaxis = dict(title = 'grade'),
                   yaxis = dict(title = 'price'))
fig=go.Figure(trace,layout)
fig.show()


trace=[go.Scatter(x=xTest[:,0],y=yTest-prediction,mode="markers",name="residual"),go.Scatter(x=xTest[:,0],y=prediction,mode="markers", name="regretion line")]
layout = go.Layout(xaxis = dict(title = 'grade'),
                   yaxis = dict(title = 'price'))
fig=go.Figure(trace,layout)
fig.show()
In [24]:
# Solution (Punto 5)
print(f"train r^2= {regLin.score(xTrain,yTrain)}")
print(f"test r^2= {regLin.score(xTest,yTest)}")
train r^2= 0.5464482507344866
test r^2= 0.43453224414792224

2.3 (Regressione lineare multipla)¶

Dagli esercizi precedenti abbiamo notato che c'è una relazione tra la variabile price e le variabili eslicative sqft_living (dimensione dell'appartamento) e grade (classe di appartenenza dell'abitazione). Sino ad ora, queste relazioni sono state descritte (in maniera piu' o meno accurata) da 2 modelli indipendenti di regressione lineare semplice.

In questa parte dell'esercizio useremo le due variabili esplicative sqft_living e grade contemporaneamente per provare a spiegare la variabile target price.

Nello specifico, utilizzando sempre il dataset di training dfTrain caricato prima, si vuole costruire un unico modello di regressione lineare multipla che spieghi la relazione tra la variabile target e le 2 variabili splicative sqft_living e grade.

Si eseguano i seguenti punti:

  • Generate uno scatter plot 3D delle osservazioni (sull'asse x mettete le osservazioni della variabile sqft_living, sull'asse y le osservazioni della variabile grade, e sull'asse z le osservazioni della variabile target price). Guardate la cella di Hint sotto per capire come generare uno scatter plot tridimensionale.
  • Calcolate i parametri del modello di regressione lineare multipla y=x*w+b = sqft_living*w1 + grade*w2 + b
  • Disegnare in un unico grafico lo scatter plot tridimensionale delle osservazioni del trainig set e il modello di regressione lineare (questo modello sarà un piano). Guardate la cella di Hint sotto per capire come disegnare un piano nello spazio.
  • Calcolate il valore della funzione y = x*w+b per ogni valore di x del training set e del test set. Si plottino, in 2 figure separate, i residui sul training test e sul test set.
  • Calcolate il coeffiente di determinazione R^2e il SSE sia sul training set che sul test set. Il coefficiente $R^2$ del modello di regressione lineare multipla è piu' alto rispetto all' $R^2$ ottenuto dai singoli modelli di regressione lineare semplice? Quale tra i 3 modelli di regressione lineare calcolati sino ad ora (2 modelli di regressione lineare semplice calcolati al punto 2.1 e 2.2 e il modello di regressione lineare multipla calcolato ora) predice meglio il prezzo di vendita delle case? Hint: Guardare l' $R^2$ sui dati di test.

Nota: Si esegua la cella sotto per caricare le variabile esplicative in un unico array a DUE dimensione, con m righe e 2 colonne.

In [25]:
xTrain = dfTrain[['sqft_living', 'grade']].values
xTest = dfTest[['sqft_living', 'grade']].values
xTrain
Out[25]:
array([[1990,    8],
       [2900,    8],
       [ 920,    6],
       [4830,   11],
       [2120,    8],
       [2200,    7],
       [1410,    7],
       [2390,    9],
       [2420,    8],
       [2481,    8],
       [4060,   10],
       [2820,   10],
       [ 840,    5],
       [1520,    6],
       [2440,    8],
       [1090,    7],
       [3590,    9],
       [ 830,    6],
       [2460,    7],
       [1640,    8],
       [2380,    8],
       [1010,    7],
       [2220,    7],
       [2620,    9],
       [3460,    9],
       [3770,   11],
       [1180,    6],
       [1650,    6],
       [1750,    8],
       [1260,    6],
       [1540,    7],
       [3270,    8],
       [1280,    6],
       [3920,    9],
       [1040,    7],
       [1129,    7],
       [2590,    9],
       [2830,   10],
       [1240,    6],
       [1640,    7],
       [1930,    7],
       [1680,    7],
       [1520,    7],
       [2690,    9],
       [ 520,    5],
       [2970,    8],
       [1460,    6],
       [3180,    8],
       [2550,    9],
       [1850,    8],
       [4120,   10],
       [2230,    8],
       [2800,    8],
       [2330,    9],
       [1430,    7],
       [1830,    8],
       [1290,    6],
       [1140,    6],
       [2630,    9],
       [1600,    7],
       [2070,    8],
       [1060,    6],
       [1347,    7],
       [2000,    7],
       [ 970,    7],
       [1460,    7],
       [1010,    6],
       [2120,    8],
       [2260,    7],
       [ 910,    6],
       [2790,    8],
       [1610,    7],
       [3680,    8],
       [1790,    7],
       [4285,   10],
       [1270,    8],
       [1540,    7],
       [1580,    8],
       [1330,    6],
       [1650,    7],
       [1710,    7],
       [5860,   10],
       [4560,   12],
       [1700,    7],
       [1560,    6],
       [3540,    9],
       [1520,    7],
       [2160,    8],
       [1410,    6],
       [2290,    7],
       [2160,    9],
       [1340,    7],
       [1800,    7],
       [1120,    7],
       [2050,    7],
       [1500,    7],
       [3220,    9],
       [1970,    7],
       [1140,    7],
       [1600,    8],
       [1960,    7],
       [2790,    9],
       [2980,    8],
       [2160,    7],
       [4360,   10],
       [ 850,    5],
       [1670,    8],
       [1810,    7],
       [1390,    7],
       [1590,    7],
       [2400,    7],
       [2290,    8],
       [1300,    8],
       [2080,    8],
       [1630,    7],
       [1530,    7],
       [2200,    8],
       [2560,    8],
       [1620,    6],
       [1510,    7],
       [1180,    7],
       [5710,   11],
       [3150,    9],
       [2590,    9],
       [2550,    8],
       [2110,    7],
       [1750,    7],
       [2540,    8],
       [2720,    9],
       [3600,    8],
       [2900,    8],
       [2100,    9],
       [2260,    7],
       [1410,    7],
       [3060,    8],
       [1830,    7],
       [2530,    8],
       [1330,    7],
       [2090,    7],
       [2370,    8],
       [1800,    8],
       [1110,    6],
       [1740,    8],
       [1910,    7],
       [2280,    7],
       [1610,    7],
       [1050,    7],
       [1140,    6],
       [2270,    8],
       [ 940,    6],
       [3480,   10]])
In [26]:
# Hint (3D scatter plot)

x = np.random.randn(1000)
y = np.random.randn(1000)
z = x**2 + y

trace = go.Scatter3d(x = x, y = y, z = z, mode = 'markers', marker = dict(size = 3) ) 
layout = go.Layout(scene = dict(xaxis = dict(title = 'x'), yaxis = dict(title = 'y'), zaxis = dict(title = 'z')))

fig = go.Figure([trace], layout)
py.iplot(fig)
In [27]:
# Hint (Disegnare piano nello spazio che passa per punti allineati)

x = np.array([1,2,3])
y = np.array([1,2,3])
z = np.zeros((3,3))

for ind1 in range(len(x)):
    for ind2 in range(len(y)):
        z[ind1,ind2] = 5*x[ind1] + 10*y[ind2] - 0.4   # Equazione del piano

trace = go.Surface(x = x, y = y, z = z) 
layout = go.Layout(scene = dict(xaxis = dict(title = 'x'), yaxis = dict(title = 'y'), zaxis = dict(title = 'z')))

fig = go.Figure([trace], layout)
py.iplot(fig)
In [28]:
# Solution (punto 1)
# Hint (3D scatter plot)

x = xTrain[0]
y = xTrain[1]
z = x*y

trace = go.Scatter3d(x = x, y = y, z = z, mode = 'markers', marker = dict(size = 3) )
layout = go.Layout(scene = dict(xaxis = dict(title = 'x'), yaxis = dict(title = 'y'), zaxis = dict(title = 'z')))

fig = go.Figure([trace], layout)
py.iplot(fig)
In [29]:
# Solution (punto 2)
regLin= linear_model.LinearRegression()
regLin.fit(xTrain,yTrain)
print(f"w1={regLin.coef_[0]} w2={regLin.coef_[1]} b={regLin.intercept_}")
w1=116.93347794762856 w2=108107.19143816349 b=-530314.3651233781
In [30]:
# Solution (punto 3)
x = xTrain[0]
y =xTrain[1]
z = np.zeros((3,3))

for ind1 in range(len(x)):
    for ind2 in range(len(y)):
        z[ind1,ind2] = regLin.coef_[0]*x[ind1] + regLin.coef_[1]*y[ind2] - regLin.intercept_# Equazione del piano

trace = go.Surface(x = x, y = y, z = z)
layout = go.Layout(scene = dict(xaxis = dict(title = 'x'), yaxis = dict(title = 'y'), zaxis = dict(title = 'z')))

fig = go.Figure([trace], layout)
py.iplot(fig)
In [31]:
# Solution (Punto 4)
regLin= linear_model.LinearRegression()
regLin.fit(xTest,yTest)
prediction=regLin.predict(xTest)
trace=[go.Scatter(x=xTest[:,0],y=yTest,mode="markers",name="dataset data"),go.Scatter(x=xTest[:,0],y=prediction,mode="markers", name="prediction")]
layout = go.Layout(xaxis = dict(title = 'grade'),
                   yaxis = dict(title = 'price'))
fig=go.Figure(trace,layout)
fig.show()


trace=[go.Scatter(x=xTest[:,0],y=yTest-prediction,mode="markers",name="residual"),go.Scatter(x=xTest[:,0],y=prediction,mode="markers", name="regretion line")]
layout = go.Layout(xaxis = dict(title = 'grade'),
                   yaxis = dict(title = 'price'))
fig=go.Figure(trace,layout)
fig.show()
In [32]:
# Solution (punto 5)
print(f"train r^2= {regLin.score(xTrain,yTrain)}")
print(f"test r^2= {regLin.score(xTest,yTest)}")
train r^2= 0.579652412165909
test r^2= 0.45205102967967925